#ifndef LONGKEY_COMMON_CONTROLLED_OBJECT_H_
#define LONGKEY_COMMON_CONTROLLED_OBJECT_H_

#include <atlcom.h>
#include "../base/scoped_ptr.h"
#include "../base/logging.h"
#include "../base/scoped_ptr_address.h"

template <class Base>
class ControlledObject : public CComContainedObject<Base>
{
public:
	typedef CComContainedObject<Base> BaseClass;
	typedef ControlledObject<Base> ControlledObj;


	explicit ControlledObject(void* pv) : BaseClass(pv) {}
	virtual ~ControlledObject() {}

	STDMETHOD(QueryInterface)(REFIID iid, void **ppv) throw()
	{
		return _InternalQueryInterface(iid, ppv);
	}

	static HRESULT WINAPI CreateInstance(IUnknown* controlling_unknown,
		ControlledObj** pp) throw()
	{
		ASSERT1(pp);
		if (!controlling_unknown)
			CORE_LOG(LW, (_T("[CreateInstance - controlling_unknown is NULL]")));

		**pp = NULL;
		scoped_ptr<ControlledObj> p(new ControlledObj(controlling_unknown));
		if (!p.get())
			return E_OUTOFMEMORY;

		HRESULT hr = p->FinalConstruct();
		if (FAILED(hr))
			return hr;

		**pp = p.release();
		return S_OK;
	}

	template <class Q>
	HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) throw()
	{
		return QueryInterface(__uuidof(0), reinterpret_cast<void**>(pp));
	}
};

#endif	// LONGKEY_COMMON_CONTROLLED_OBJECT_H_